home *** CD-ROM | disk | FTP | other *** search
- /* Object module converter (comf) */
- /* ============================== */
- /* */
- /* Copyright (c) 1991, Stuart G. Phillips. All rights reserved. */
- /* */
- /* Permission is granted for non-commercial use of this software. */
- /* You are expressly prohibited from selling this software in any form, */
- /* distributing it with another product, or removing this notice. */
- /* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR */
- /* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED */
- /* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR */
- /* PURPOSE. */
- /* */
- /* This program accepts as input a program file in Microsoft .EXE */
- /* format and relocates it for loading into an MIO IO processor. */
- /* A new header is written that identifies the file as an MIO .LOD file */
- /* and provides the initial entry point for the down load module. */
- /* file. */
- /* */
- /* */
-
-
- #include <stdio.h>
- #include <stdlib.h>
- #include <fcntl.h>
- #include <sys\stat.h>
- #include <io.h>
- #include "objform.h"
-
- #define BUFSIZE 1024
-
- /* Local procedure declarations */
-
- static void read_blk(FILE *,char *,int);
- static void write_blk(FILE *,char *,int);
- static int sort_rel(const void *,const void *);
-
- /* Static data declarations */
-
- static char in_buf[BUFSIZE];
- static char out_buf[BUFSIZE];
- static char buffer[BUFSIZE];
-
-
- void usage()
- {
- printf("Usage: comf infile outfile [base]\n");
- printf(" base = code base for relocation (default = 0)\n");
- }
-
-
-
- void main(argc,argv)
- int argc;
- char *argv[];
- {
- struct EXEHDR *exe_hdr;
- struct LODHDR *lod_hdr;
- struct RELITEM *rel_table = (struct RELITEM *)
- calloc(10000,sizeof(struct RELITEM));
- struct RELITEM rel;
- FILE *infile,*infile2,*outfile;
- unsigned short nrel, rel_cnt, base_cs, count, i;
- long position, offset, image_size;
- int fd;
-
- if (argc < 3) {
- usage();
- exit(1);
- }
-
- if ((infile = fopen(argv[1],"rb")) == NULL) {
- printf ("Cannot open input file - %s\n", argv[1]);
- exit(1);
- }
-
- infile2 = fopen(argv[1],"rb");
-
- if ((outfile = fopen(argv[2],"wb")) == NULL) {
- printf ("Cannot open output file - %s\n");
- exit(1);
- }
-
- if (argc == 4){
- /* Code segment supplied */
- if (!sscanf(argv[3],"%x",&base_cs)){
- printf("Invalid code segment - %s\n",argv[3]);
- exit(1);
- }
- } else
- base_cs = 0x10;
-
- /* Firstly process the headers of each file. Read in the first */
- /* block of the input (.EXE) file and use the information it */
- /* contains to construct the output (.LOD) file header. */
-
- lod_hdr = (struct LODHDR *) out_buf;
- exe_hdr = (struct EXEHDR *) in_buf;
-
- read_blk(infile,in_buf,32);
-
- if (exe_hdr->magic != EXE_MAGIC)
- {
- printf("Input file is not a valid .EXE file\n");
- exit(1);
- }
-
- rel_cnt = exe_hdr->nreloc;
- printf("Relocation Count = %d\n",rel_cnt);
-
- lod_hdr->magic = LOD_MAGIC;
- lod_hdr->version = LOD_VERSION;
- lod_hdr->val_offset = exe_hdr->val_ip;
- lod_hdr->val_seg = base_cs;
-
- if ((fd = open(argv[1],O_BINARY|O_RDONLY)) == -1){
- printf("Can't get modification time for file - %s\n",argv[1]);
- exit(1);
- }
- (void)getftime(fd,(struct ftime *)&lod_hdr->time_stamp);
- close(fd);
-
- image_size = ((long) exe_hdr->npages * 512L) -
- ((long) exe_hdr->hdrsize * 16L) -
- (512L - (long)exe_hdr->nbytes );
-
- lod_hdr->image_size = image_size;
-
- printf("Load size = %05lx\n",image_size);
-
- /* Output the header to the .LOD file */
-
- write_blk(outfile,(char *)lod_hdr,sizeof(struct LODHDR));
-
- /* Seek input file over .EXE header */
-
- if (fseek(infile,((long)exe_hdr->hdrsize * 16L),SEEK_SET) != 0){
- printf("Seek error on .EXE Header\n");
- exit(1);
- }
-
- /* Position infile2 input stream to the first relocation item */
-
- if (fseek(infile2, (long)exe_hdr->rel_offset, SEEK_SET) != 0) {
- printf("Seek error on relocation items\n");
- exit(1);
- }
-
- printf("Reading relocation items.....\n");
-
- for (nrel = 0;nrel < rel_cnt;nrel++)
- read_blk(infile2,(char *)&rel_table[nrel],sizeof(struct RELITEM));
-
- printf("Sorting relocation items.....\n");
-
- qsort((void *)rel_table,rel_cnt,sizeof(struct RELITEM),sort_rel);
-
- /* Copy across the image to the output file relocating as we go. */
- position = 0;
-
- for (nrel = 0;nrel < rel_cnt;nrel++){
- /* Process a relocation item */
-
- offset = (long)rel_table[nrel].offset +
- (16L * (long)rel_table[nrel].segment);
-
- /* Copy the input to the output until we reach the word
- * to be relocated.
- */
-
- while (position != offset){
- if (offset - position > BUFSIZE)
- count = BUFSIZE;
- else
- count = (unsigned) offset - position;
-
- read_blk(infile,in_buf,count);
- write_blk(outfile,in_buf,count);
- position += (long)count;
- image_size -= (long)count;
- }
-
- /* Read the word to be relocated and..... relocate it ! */
-
- read_blk(infile,(char *)&i,2);
-
- i += base_cs;
- write_blk(outfile,(char *)&i,2);
- position += 2;
- image_size -= 2;
- }
-
- /* No more relocation items - copy the remainder of the input
- * to the output and we're done.
- */
-
- while (image_size) {
- count = image_size > BUFSIZE ? BUFSIZE : (unsigned) image_size;
- read_blk(infile,in_buf,count);
- write_blk(outfile,in_buf,count);
- image_size -= (long) count;
- }
-
- exit(0);
- }
-
- static void read_blk(fdesc,buffer,count)
- FILE *fdesc;
- char *buffer;
- int count;
- {
- if (fread(buffer,count,1,fdesc) == 0){
- printf("Unexpected EOF on input file\n");
- exit(1);
- }
- }
-
-
- static void write_blk(fdesc,buffer,count)
- FILE *fdesc;
- char *buffer;
- int count;
- {
- if (fwrite(buffer,count,1,fdesc) == 0){
- printf("Error on writing output file\n");
- exit(1);
- }
- }
-
- int sort_rel(const void *a,const void *b)
- {
- long *x = (long *)a;
- long *y = (long *)b;
-
- if (*x == *y) return (0);
-
- return (*x > *y ? 1 : -1);
- }
-